-module(client_manager).
-author("shendatian").

-behaviour(gen_server).

%% API
-export([
  start/0,
  add/0,
  online_user_amount/0
]).

%% gen_server callbacks
-export([init/1,
  handle_call/3,
  handle_cast/2,
  handle_info/2,
  terminate/2,
  code_change/3]).

-record(state, {num, max}).

-define(SERVER, <<"xiaoquan.com">>).
-define(USER_NUM, 1000).

-record(client_user, {
  id = undefined,
  pid = undefined
}).

%% -record(user_msg_state, {
%%   id = undefined,
%%   send = 0,
%%   receives = 0
%% }).

add() ->
  gen_server:cast(?MODULE, {add}).

start() ->
  gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).


init([]) ->
  ets:new(client_user, [named_table, public, set, {keypos, #client_user.id}]),

%%   ets:new(user_msg_state, [named_table, public, set, {keypos, #user_msg_state.id}]),
  init_data(),
  erlang:send_after(1000, self(), {loop}),
  man(),
  {ok, #state{num = 1, max = 200}}.


handle_call(_Request, _From, State) ->
  {reply, ok, State}.

handle_cast({mfc, M, F, A}, State) ->
  catch apply(M, F, A),
  {noreply, State};
handle_cast({add}, State) ->
  {noreply, State#state{max = State#state.max + 1}};
handle_cast(_Request, State) ->
  {noreply, State}.

handle_info({loop}, State) ->
  Rand = 10,
%%   io:format("rand manager : ~p~n", [Rand]),
  erlang:send_after(Rand * 1000, self(), {loop}),
  UserID = application:get_env(client, user_id, 100000),
  Num = State#state.num,
  Num1 = case Num > State#state.max of
    true ->
      Num;
    false ->
      [begin
         [begin
            N1 = (N - 1)*1000 + X,
            ID = erlang:integer_to_list(UserID + N1),
%%             io:format("ID :~p~n", [ID])
            case supervisor:start_child(client_sup, [ID]) of
              {ok, Pid} ->
                ets:insert(client_user, #client_user{id=ID, pid = Pid});
              Err ->
                io:format("connect err:~p~n", [Err])
            end
          end || X <- lists:seq(1, 50)]
       end || N <- lists:seq((Num - 1) * 2 + 1, Num * 2)],
      Num + 1
  end,
  online_user_amount(),
  {noreply, State#state{num = Num1}};

handle_info(_Info, State) ->
  {noreply, State}.

terminate(_Reason, _State) ->
  ets:delete_all_objects(client_user),
%%   ets:delete_all_objects(user_msg_state),
  ok.

code_change(_OldVsn, State, _Extra) ->
  {ok, State}.

%% ============== func ================
init_data() ->
%%   [Begin, End] = application:get_env(client, user_num, [0, 0]),
%%   Users = lists:seq(Begin, End),
  ok.


online_user_amount() ->
  OnlineUser = get_current_num(),
  io:format("online user amount:~p~n", [OnlineUser]),
  ok.

%% user_online2(From, To) ->
%% %%   io:format("user connect from ~p to ~p ~n", [From, To]),
%%   lists:foreach(fun(N) ->
%%     ID = erlang:integer_to_list(N),
%% %%     io:format("id : ~p~n", [ID]),
%%     case  supervisor:start_child(client_sup, [ID]) of
%%       {ok, Pid} ->
%%         ets:insert(client_user, #client_user{id=ID, pid = Pid});
%%       Err ->
%%         io:format("connect err:~p~n", [Err])
%%     end
%%   end, lists:seq(From, To)),
%%   ok.

%% get_finish_num() ->
%%   case erlang:get('finish_online') of
%%     undefined -> 0;
%%     Num -> Num
%%   end.
%%
%% update_finish_num(N) ->
%%   erlang:put('finish_online', N).

get_current_num() ->
  case ets:info(client_user, size) of
    undefined -> 0;
    Value -> Value
  end.

man() ->
  io:format("~n~n~n~n", []),
  io:format("************ operation option ***********~n", []),
  io:format("1:client_manager:online_user_amount(), which tell you the amount current online.~n", []),
  io:format("2:client_manager:man(), for help.~n", []),
  io:format("**the client will loop on 10 seconds, and send msg to server from which
  user online.and the user online is step by step, 50 users one time.~n~n", []),
  ok.

